001 package EVolve;
002
003 /* EVolve - an Extensible Software Visualization Framework
004 * Copyright (C) 2001-2002 Qin Wang
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Library General Public
008 * License as published by the Free Software Foundation; either
009 * version 2 of the License, or (at your option) any later version.
010 *
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Library General Public License for more details.
015 *
016 * You should have received a copy of the GNU Library General Public
017 * License along with this library; if not, write to the
018 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
019 * Boston, MA 02111-1307, USA.
020 */
021
022 /*
023 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
024 */
025
026 import EVolve.*;
027 import EVolve.exceptions.DataProcessingException;
028 import EVolve.exceptions.CancelLoadDataException;
029 import EVolve.exceptions.EVolveException;
030 import EVolve.data.NumericStringComparator;
031 import EVolve.data.*;
032 import java.io.*;
033 import java.util.*;
034 import javax.swing.*;
035
036 public class DemoSource implements DataSource {
037 private final String dsourceName = "DemoSource";
038 private String fn = null; // data file name
039
040 private RandomAccessFile file;
041
042 private EntityBuilder classBuilder;
043
044 private EntityBuilder threadBuilder;
045
046 private EntityBuilder methodBuilder;
047 private FieldDefinition methodDefiningClass;
048
049 private EntityBuilder locationBuilder;
050
051 private EntityBuilder sizeBuilder;
052
053 private EventBuilder allocationBuilder;
054 private FieldDefinition allocationObjectCount;
055 private FieldDefinition allocationObjectSize;
056 private FieldDefinition allocationBytecode;
057 private FieldDefinition allocationObjectType;
058 private FieldDefinition allocationThread;
059 private FieldDefinition allocationMethod;
060 private FieldDefinition allocationLocation;
061 private FieldDefinition allocationSize;
062 private FieldDefinition allocationFieldSum;
063 private FieldDefinition allocationFieldCounter;
064
065 private EventBuilder invocationBuilder;
066 private FieldDefinition invocationNumber;
067 private FieldDefinition invocationBytecode;
068 private FieldDefinition invocationThread;
069 private FieldDefinition invocationMethod;
070 private FieldDefinition invocationLocation;
071 private FieldDefinition invocationFieldCounter;
072
073
074 private ElementDefinition[] definition;
075 private int definitionCounter;
076
077 private TreeMap classMap;
078 private TreeMap threadMap;
079 private TreeMap methodMap;
080 private TreeMap locationMap;
081 private TreeMap sizeMap;
082
083 private long counter[];
084
085 public void init() throws EVolveException {
086 String lastName = fn;
087
088 fn = Scene.getDataFileName();
089 if (fn == null) {
090 JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastDataDir());
091 if (fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
092 try {
093 file = new RandomAccessFile(fc.getSelectedFile(), "r");
094 fn = fc.getSelectedFile().getName();
095 Scene.setDataFilename(fc.getSelectedFile().getPath());
096 Scene.getUIManager().setLastDataDir(fc.getSelectedFile().getPath());
097 Scene.setDataFilename(null);
098 } catch (IOException e) {
099 throw new DataProcessingException("IO exception occurred when access data file.");
100 }
101 } else {
102 fn = lastName;
103 throw new CancelLoadDataException();
104 }
105 } else {
106 try {
107 file = new RandomAccessFile(fn, "r");
108 } catch (IOException e) {
109 throw new DataProcessingException("File loading failed.");
110 }
111 }
112
113 }
114
115 public void startBuildDefinition() throws DataProcessingException {
116 String[] propertySum = {"time","sum"};
117 String[] propertyCount = {"time","count"};
118 String[] propertyAmount = {"amount"};
119 String[] propertyCoordinate = {"time","coordinate"};
120 String[] propertyIndicator = {"indicator"};
121 String[] propertyThread = {"reference","thread"};
122
123 definition = new ElementDefinition[7];
124
125 classBuilder = new EntityBuilder("Class", "Class");
126 definition[0] = classBuilder.buildDefinition();
127
128 threadBuilder = new EntityBuilder("Thread", "Thread");
129 definition[1] = threadBuilder.buildDefinition();
130
131 methodBuilder = new EntityBuilder("Method", "Method");
132 methodDefiningClass = methodBuilder.buildReferenceDefinition("Defining Class", classBuilder, null, "Defining class of the method");
133 definition[2] = methodBuilder.buildDefinition();
134
135 locationBuilder = new EntityBuilder("Location", "Location in Method");
136 definition[3] = locationBuilder.buildDefinition();
137
138 sizeBuilder = new EntityBuilder("Size", "Object Size");
139 sizeBuilder.addComparator(new NumericStringComparator());
140 definition[4] = sizeBuilder.buildDefinition();
141
142 allocationBuilder = new EventBuilder("Object Allocation", "Object allocation event");
143 allocationFieldSum = allocationBuilder.buildValueDefinition("Memory Allocated", propertySum, "Size of memory allocated");
144 allocationFieldCounter = allocationBuilder.buildValueDefinition("Allocations", propertyCount, "Number of objects allocated");
145 allocationObjectCount = allocationBuilder.buildValueDefinition("Object Count", propertyAmount, "Number of objects allocated");
146 allocationObjectSize = allocationBuilder.buildValueDefinition("Memory Allocated", propertyAmount, "Size of memory allocated");
147 allocationBytecode = allocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence");
148 allocationObjectType = allocationBuilder.buildReferenceDefinition("Object Type", classBuilder, null, "Type of the object");
149 allocationThread = allocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the object is allocated");
150 allocationMethod = allocationBuilder.buildReferenceDefinition("Allocating Methods", methodBuilder, null, "Method that creates the object");
151 allocationLocation = allocationBuilder.buildReferenceDefinition("Allocating Locations", locationBuilder, null, "Location where the object is created");
152 allocationSize = allocationBuilder.buildReferenceDefinition("Allocation Size", sizeBuilder, null, "Allocation Size");
153 definition[5] = allocationBuilder.buildDefinition();
154
155 invocationBuilder = new EventBuilder("Method Invocation", "Method invocation event");
156 invocationFieldCounter = invocationBuilder.buildValueDefinition("Invocations", propertyCount, "Total number of invocations");
157 invocationNumber = invocationBuilder.buildValueDefinition("Number of Invocations", propertyAmount, "Total number of invocations");
158 invocationBytecode = invocationBuilder.buildValueDefinition("Bytecode", propertyCoordinate, "Bytecode sequence");
159 invocationThread = invocationBuilder.buildReferenceDefinition("Thread", threadBuilder, propertyThread, "Thread in which the method is invoked");
160 invocationMethod = invocationBuilder.buildReferenceDefinition("Method", methodBuilder, null, "Method that is invoked");
161 invocationLocation = invocationBuilder.buildReferenceDefinition("Invoking Locations", locationBuilder, null, "Location where the method is invoked");
162 definition[6] = invocationBuilder.buildDefinition();
163
164 definitionCounter = -1;
165 counter = new long[definition.length];
166 for (int i=0; i<counter.length; i++)
167 counter[i] = 0;
168 }
169
170 public ElementDefinition getNextDefinition() throws DataProcessingException {
171 definitionCounter++;
172 if (definitionCounter < definition.length) {
173 return definition[definitionCounter];
174 } else {
175 return null;
176 }
177 }
178
179 private String getSub(String line, int part) {
180 int start = line.indexOf(' ') + 1;
181 int i = 1;
182 while (i < part) {
183 start = line.indexOf(' ', start) + 1;
184 i++;
185 }
186 int end = line.indexOf(' ', start);
187 if (end == -1) {
188 return line.substring(start);
189 } else {
190 return line.substring(start, end);
191 }
192 }
193
194 public void startBuildEntity() throws DataProcessingException {
195 try {
196 file.seek(0);
197
198 classMap = new TreeMap();
199 threadMap = new TreeMap();
200 methodMap = new TreeMap();
201 locationMap = new TreeMap();
202 sizeMap = new TreeMap();
203 } catch (IOException e) {
204 throw new DataProcessingException("File processing failed.");
205 }
206 }
207
208 public Entity getNextEntity() throws DataProcessingException {
209 try {
210 Entity returnVal = null;
211 String line = file.readLine();
212
213 while ((returnVal == null) && (line != null) && (line.length()>0)) {
214 line = line.trim();
215 char ch = line.charAt(0);
216
217 if (ch == 'C') {
218 classBuilder.newEntity(getSub(line, 1));
219 returnVal = classBuilder.buildEntity();
220 classMap.put(getSub(line, 2), returnVal);
221 } else if (ch == 'T') {
222 threadBuilder.newEntity(getSub(line, 1));
223 returnVal = threadBuilder.buildEntity();
224 threadMap.put(getSub(line, 2), returnVal);
225 } else if (ch == 'M') {
226 methodBuilder.newEntity(getSub(line, 1));
227 methodBuilder.addReferenceField(methodDefiningClass, (Entity)(classMap.get(getSub(line, 3))));
228 returnVal = methodBuilder.buildEntity();
229 methodMap.put(getSub(line, 2), returnVal);
230 } else if (ch == 'L') {
231 locationBuilder.newEntity(getSub(line, 1));
232 returnVal = locationBuilder.buildEntity();
233 locationMap.put(getSub(line, 2), returnVal);
234 } else if (ch == 'O') {
235 String size = getSub(line, 6);
236 if (!sizeMap.containsKey(size)) {
237 sizeBuilder.newEntity(size);
238 returnVal = sizeBuilder.buildEntity();
239 sizeMap.put(size, returnVal);
240 }
241 counter[5]++;
242 } else if (ch == '+') {
243 counter[6]+=2;
244 }
245
246 if (returnVal == null) {
247 line = file.readLine();
248 }
249 }
250
251 return returnVal;
252 } catch (IOException e) {
253 throw new DataProcessingException("File processing failed.");
254 }
255 }
256
257 public void startBuildEvent() throws DataProcessingException {
258 try {
259 file.seek(0);
260 } catch (IOException e) {
261 throw new DataProcessingException("File processing failed.");
262 }
263 }
264
265 public Event getNextEvent() throws DataProcessingException {
266 try {
267 Event returnVal = null;
268 String line = file.readLine();
269
270 while ((returnVal == null) && (line != null)) {
271 line = line.trim();
272 char ch = line.charAt(0);
273
274 if (ch == 'O') {
275 allocationBuilder.newEvent();
276 String size = getSub(line, 6);
277 allocationBuilder.addValueField(allocationObjectCount, 1);
278 allocationBuilder.addValueField(allocationObjectSize, Integer.parseInt(getSub(line, 6)));
279 allocationBuilder.addValueField(allocationFieldCounter, 1);
280 allocationBuilder.addValueField(allocationFieldSum, Integer.parseInt(getSub(line, 6)));
281 allocationBuilder.addValueField(allocationBytecode, Integer.parseInt(getSub(line, 1)));
282 allocationBuilder.addReferenceField(allocationObjectType, (Entity)(classMap.get(getSub(line, 5))));
283 allocationBuilder.addReferenceField(allocationThread, (Entity)(threadMap.get(getSub(line, 2))));
284 allocationBuilder.addReferenceField(allocationMethod, (Entity)(methodMap.get(getSub(line, 3))));
285 allocationBuilder.addReferenceField(allocationLocation, (Entity)(locationMap.get(getSub(line, 4))));
286 allocationBuilder.addReferenceField(allocationSize, (Entity)(sizeMap.get(size)));
287 returnVal = allocationBuilder.buildEvent();
288 } else if (ch == '+') {
289 invocationBuilder.newEvent();
290 invocationBuilder.addValueField(invocationNumber, 1);
291 invocationBuilder.addValueField(invocationFieldCounter, 1);
292 invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1)));
293 invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2))));
294 invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3))));
295 invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4))));
296 returnVal = invocationBuilder.buildEvent();
297 } else if (ch == '-') {
298 invocationBuilder.newEvent(true);
299 invocationBuilder.addValueField(invocationNumber, 1);
300 invocationBuilder.addValueField(invocationBytecode, Integer.parseInt(getSub(line, 1)));
301 invocationBuilder.addReferenceField(invocationThread, (Entity)(threadMap.get(getSub(line, 2))));
302 invocationBuilder.addReferenceField(invocationMethod, (Entity)(methodMap.get(getSub(line, 3))));
303 invocationBuilder.addReferenceField(invocationLocation, (Entity)(locationMap.get(getSub(line, 4))));
304 returnVal = invocationBuilder.buildEvent();
305 }
306
307 if (returnVal == null) {
308 line = file.readLine();
309 }
310 }
311
312 return returnVal;
313 } catch (IOException e) {
314 throw new DataProcessingException("File processing failed.");
315 }
316 }
317
318 public String getName() {
319 return dsourceName;
320 }
321
322 public String getFileName() {
323 return fn;
324 }
325
326 public long getTotalNumberOfEvents() {
327 long total = 0;
328
329 for (int i=0; i<definition.length; i++)
330 total = total + counter[i];
331
332 return total;
333 }
334
335 public long getNumberOfEvents(String definitionName) {
336 long number = 0;
337
338 for (int i=0; i<definition.length; i++) {
339 if (definition[i].getName().equals(definitionName)) {
340 number = counter[i];
341 if (definitionName.equals("Method Invocation")) number = number/2;
342 break;
343 }
344 }
345
346 return number;
347 }
348 }